import java.util.*;

public class Main {
    //BM33 二叉树的镜像
    //时间复杂度：O(N) 空间复杂度：O(N)
    public TreeNode Mirror (TreeNode pRoot) {
        // write code here
        //利用递归
        //先处理最左节点和最右节点，之后才是根节点
        if(pRoot == null) {
            return null;
        }
        //找到子树的最左面
        TreeNode left = Mirror(pRoot.left);
        //找到子树的最右面
        TreeNode right = Mirror(pRoot.right);

        //把其根节点的左右进行交换
        pRoot.left = right;
        pRoot.right = left;

        return pRoot;
    }

    //BM32 合并二叉树
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        // write code here
        if(t1 == null) {
            return t2;
        }
        if(t2 == null) {
            return t1;
        }
        TreeNode head = new TreeNode(t1.val + t2.val);
        head.left = mergeTrees(t1.left,t2.left);
        head.right = mergeTrees(t1.right,t2.right);
        return head;
    }

    //BM28 二叉树的最大深度
    public int maxDepth (TreeNode root) {
        // write code here
        if(root == null) {
            return 0;
        }
        //返回子树的深度 + 1
        return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
    }

    //BM25 二叉树的后序遍历
    //左右根
    private void postorder(List<Integer> list, TreeNode root) {
        if (root == null) {
            return;
        }
        postorder(list, root.left);
        postorder(list, root.right);
        list.add(root.val);
    }
    public int[] postorderTraversal (TreeNode root) {
        // write code here
        List<Integer> list = new ArrayList<>();

        postorder(list, root);

        int[] ret = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            ret[i] = list.get(i);
        }

        return ret;
    }

    //BM24 二叉树的中序遍历
    //左根右
    private void inorder(List<Integer> list,TreeNode root) {
        if(root == null) {
            return;
        }
        inorder(list,root.left);
        list.add(root.val);
        inorder(list,root.right);
    }
    public int[] inorderTraversal (TreeNode root) {
        // write code here
        List<Integer> list = new ArrayList<>();

        inorder(list,root);

        int[] ret = new int[list.size()];
        for(int i = 0;i < list.size();i++) {
            ret[i] = list.get(i);
        }

        return ret;
    }

    //BM24 二叉树的前序遍历
    //根左右，存放到链表中，最后在进行返回数组
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
        public TreeNode(int val) {
            this.val = val;
        }
    }
    private void preorder(List<Integer> list,TreeNode root) {
        if(root == null) {
            return;
        }
        //根左右
        list.add(root.val);
        preorder(list,root.left);
        preorder(list,root.right);
    }
    public int[] preorderTraversal (TreeNode root) {
        // write code here
        List<Integer> list = new ArrayList<>();
        preorder(list,root);
        int[] ret = new int[list.size()];

        for(int i = 0;i < list.size();i++) {
            ret[i] = list.get(i);
        }
        return ret;
    }

    //力扣：水果成篮
    //时间复杂度：O(N) 空间复杂度：O(1)
    public int totalFruit2(int[] fruits) {
        //使用Map的K-V模型进行滑动窗口
        Map<Integer,Integer> map = new HashMap<>();

        int ret = 0;
        for(int right = 0,left = 0; right < fruits.length; right++) {
            map.put(fruits[right],map.getOrDefault(fruits[right],0) + 1);
            //这个是如果fruits[right]为0，就是0+1，否则就是返回fruits[right]的V值+1，再进行存放
            while(map.size() > 2) {
                //出窗口
                map.put(fruits[left], map.get(fruits[left]) - 1);//更新left位置的值
                if (map.get(fruits[left]) == 0) {
                    map.remove(fruits[left]);
                }
                left++;
            }
            ret = Math.max(ret,right - left + 1);
        }
        return ret;
    }
    public int totalFruit(int[] fruits) {
        int n = fruits.length;
        int[] arr = new int[n];//用于存放水果的种类和每种的个数
        int ret = 0;
        for(int right = 0,left = 0,kinds = 0; right < n; right++) {
            if(arr[fruits[right]] == 0) {
                //说明没有这个水果种类，我们把要增加一个种类
                kinds++;
            }
            //之后不论是否存在这个种类，都要在这个基础上加上一个
            arr[fruits[right]]++;
            while(kinds > 2) {
                //超过篮子可以存放的种类了，我们出窗口
                arr[fruits[left]]--;
                //可能出现：[1,2,1,3,2,3,2,2]
                if(arr[fruits[left]] == 0) {
                    //说明没有这个种类的水果了
                    kinds--;
                }
                left++;
            }
            //更新结果
            ret = Math.max(ret,right - left + 1);
        }
        return ret;
    }

    //力扣：将x减到0的最小操作数
    //时间复杂度: O(N) 空间复杂度: O(1)
    public int minOperations(int[] nums, int x) {
        //我们求把x减为0难得话，我们就从后往前想，求数组总和-x得出的值在数组中最长的长度，
        //之后数组的总长-求出的长度，就是我们最后需要的长度
        int sum = 0;
        for(int s : nums) {
            sum += s;
        }
        int tagert = sum - x;//我们求在数组中这个值的最长长度
        if(tagert < 0) {//要减的值超过了我们数组的长度
            return -1;
        }
        //使用“滑动窗口”，利用单调性
        int ret = -1;
        for(int right = 0,left = 0,tmp = 0; right < nums.length; right++) {
            tmp += nums[right];//进窗口
            while(tmp > tagert) {
                //出窗口，但是right不用往回走，left往前走就可以了
                tmp -= nums[left++];
            }
            //判断是否等于tagert，等于就更新数据
            if(tmp == tagert) {
                ret = Math.max(ret,right - left + 1);
            }
        }
        if(ret == -1) {
            return -1;
        }else {
            return nums.length - ret;
        }
    }

    //OR106 字符串加法
    private static String add(String str1,String str2) {
        StringBuilder ret = new StringBuilder();
        //从后往前遍历数组
        int index1 = str1.length() - 1;
        int index2 = str2.length() - 1;
        int carray = 0;//用于计算进位
        while(index1 >= 0 || index2 >= 0) {
            //将其字符串的值转换为整数
            int n1 = index1 >= 0 ? str1.charAt(index1) - '0' : 0;
            int n2 = index2 >= 0 ? str2.charAt(index2) - '0' : 0;
            //求和，把进位也加进去
            int sum = n1 + n2 + carray;
            carray = sum / 2;//更新新的进位
            ret.append(sum % 2);//把这个和%2加入到ret中
            //下标往前移动
            index1--;
            index2--;
        }
        if(carray > 0) {
            //这个是当进制还存在的时候，再次添加一个位数
            ret.append(carray);
        }
        return ret.reverse().toString();
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //把两次输入的值转为一次输入，并且使用spilt分割成两个字符串
        String[] str = in.nextLine().split(" ");
        String str1 = str[0];//第一个输入的字符串
        String str2 = str[1];//第二个输入的字符串
        String ret = add(str1,str2);
        System.out.println(ret);
    }

    //BM21 旋转数组的最小数字
    //时间复杂度：O(logN) 空间复杂度：O(1)
    public int minNumberInRotateArray (int[] nums) {
        // write code here
        int left = 0;
        int right = nums.length - 1;
        while(left < right) {
            //因为是旋转后的数组，所以我们用中值和right这个位置的值进行比较，因为right这面是小值
            int mid = (left + right) / 2;
            if(nums[mid] > nums[right]) {
                left = mid + 1;
            }else if(nums[mid] < nums[right]) {
                right = mid;
            }else {
                //出现相等的数字了，我们进行减小区间进行判断
                right--;
            }
        }
        return nums[left];
    }

    //BM19 寻找峰值
    //时间复杂度：O(logN) 空间复杂度：O(1)
    public int findPeakElement (int[] nums) {
        // write code here
        //二分查找，我们利用中值进行查找，每次找的都是大的值，最后的right就是最大的值
        //这里的边界一定是边界旁边的值的，因为我们要有峰值，就一定要有左右值
        int left = 0;
        int right = nums.length - 1;
        while(left < right) {
            int mid = (left + right) / 2;
            //如果中值大于了终止右面的值，说明可能右面没有山峰，所以往左面走
            if (nums[mid] > nums[mid + 1]) {
                right = mid;
            }else {
                //如果中值小于了终止右面的值，说明可能右面有山峰，所以往右面走
                left = mid + 1;
            }
        }
        return right;
    }

    //BM17 二分查找-I
    public int search (int[] nums, int target) {
        // write code here
        int left = 0;
        int right = nums.length - 1;
        while(left <= right) {
            int mid = (left + right) / 2;
            if(nums[mid] > target) {
                right = mid - 1;
            }else if (nums[mid] < target){
                left = mid + 1;
            }else {
                return mid;
            }
        }
        return -1;
    }
}
